package wisents.wicket;

import org.apache.wicket.Component;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.laughingpanda.beaninject.Inject;
import org.springframework.context.ApplicationContext;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: rabbit
 * Date: Jan 30, 2010
 * Time: 1:08:17 AM
 * To change this template use File | Settings | File Templates.
 */
public class WisentsSpringComponentInjector extends SpringComponentInjector {

    public WisentsSpringComponentInjector(WebApplication webApplication, ApplicationContext applicationContext, boolean b) {
        super(webApplication, applicationContext, b);
    }

    private Map<Inner, Object> innerMap = new HashMap<Inner, Object>();

    public boolean hasMocks() {
        return !innerMap.isEmpty();
    }

    public void mock(Class<? extends Component> clazz, String fieldName, Object value) {
        innerMap.put(new Inner(clazz, fieldName), value);
    }

    public void unmock(Class<? extends Component> clazz, String fieldName) {
        innerMap.remove(new Inner(clazz, fieldName));
    }

    @Override
    public void onInstantiation(Component component) {

        super.onInstantiation(component);

        for (Inner inner : innerMap.keySet()) {
            if (component.getClass().equals(inner.getClazz())) {
                Inject.field(inner.fieldName).of(component).with(innerMap.get(inner));
            }
        }
    }

    class Inner {
        private final Class<? extends Component> clazz;
        private final String fieldName;

        Inner(Class<? extends Component> clazz, String fieldName) {
            this.clazz = clazz;
            this.fieldName = fieldName;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Inner inner = (Inner) o;

            if (!clazz.equals(inner.clazz)) return false;
            if (!fieldName.equals(inner.fieldName)) return false;

            return true;
        }

        public Class<? extends Component> getClazz() {
            return clazz;
        }

        public String getFieldName() {
            return fieldName;
        }

        @Override
        public int hashCode() {
            return clazz.hashCode();
        }
    }
}
